package com.whosly.mysql.protocol.util;

import lombok.Getter;

import java.io.Serializable;
import java.time.Instant;

/**耗时计算
 *
 * @author fengyang
 * @date 2023/8/17 下午9:08
 * @see <a href="yueny09@163.com">mailTo: yueny09@163.com</a>
 */
public class DurationEx implements Serializable, AutoCloseable {
    @Getter
    private Instant start;

    private Instant end;
    private long duringNanos;
    private volatile boolean isRun;

    public DurationEx() {
        this(Instant.now(), true);
    }

    public DurationEx(Instant start) {
        this(start, true);
    }

    public DurationEx(Instant start, Instant isRun) {
        this(start, false);
        this.setEnd(end);
    }

    public DurationEx(Instant start, boolean isRun) {
        this.isRun = false;
        this.start = start;
        this.isRun = isRun;
    }

    private void setEnd(Instant end) {
        this.end = end;
        this.duringNanos = java.time.Duration.between(this.start, this.end).toNanos();
    }

    public void end() {
        if (this.isRun) {
            this.close();
        }
    }

    public void close() {
        if (this.isRun) {
            synchronized(this) {
                if (this.isRun) {
                    this.setEnd(Instant.now());
                    this.isRun = false;
                }
            }
        }

    }

    public long getDuringNanos() {
        return this.duringNanos;
    }

    /**
     * 耗时， 单位  toNanos
     */
    public long getDuring() {
        this.end();
        return this.getDuringNanos();
    }

    public long getDuring(boolean autoEnd) {
        return autoEnd ? this.getDuring() : this.getDuringNanos();
    }

    /**
     * 耗时， 单位  ms
     */
    public long getDuringMill() {
        return java.time.Duration.ofNanos(getDuring()).toMillis();
    }

    /**
     * 耗时， 单位  s
     */
    public long getDuringSecond() {
        return getDuringMill() / 1000;
    }

}
